/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package co.com.ces4.produccion.client.articulo;

import co.com.ces4.produccion.client.modales.interfaces.HasMateriaPrimaModal;
import co.com.ces4.client.baseView.CreateBase;
import co.com.ces4.produccion.client.ArticuloService;
import co.com.ces4.produccion.client.ArticuloServiceAsync;
import co.com.ces4.produccion.client.articulo.data.MateriaPrimaArticuloDS;
import co.com.ces4.produccion.client.articulo.data.MateriaPrimaArticuloRecord;
import co.com.ces4.produccion.client.modales.MateriaPrimaModal;
import co.com.ces4.produccion.client.utils.Loader;
import co.com.ces4.produccion.jpa.entities.Articulo;
import co.com.ces4.produccion.jpa.entities.ArticuloLinea;
import co.com.ces4.produccion.jpa.entities.DetalleSolicitudProduccion;
import co.com.ces4.produccion.jpa.entities.MateriaPrima;
import co.com.ces4.produccion.jpa.entities.MateriaPrimaArticulo;
import co.com.ces4.produccion.jpa.entities.MateriaPrimaArticuloPK;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.SelectionAppearance;
import com.smartgwt.client.types.SelectionStyle;
import com.smartgwt.client.util.BooleanCallback;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Button;
import com.smartgwt.client.widgets.Dialog;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.ButtonItem;
import com.smartgwt.client.widgets.form.fields.IntegerItem;
import com.smartgwt.client.widgets.form.fields.RadioGroupItem;
import com.smartgwt.client.widgets.form.fields.TextItem;
import com.smartgwt.client.widgets.form.validator.RegExpValidator;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.Layout;
import com.smartgwt.client.widgets.layout.SectionStackSection;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;

/**
 *
 * @author usuario
 */
public class EdicionArticulo extends CreateBase implements HasMateriaPrimaModal {

    private TextItem txtCodigoArticulo, txtDescripcionArticulo;
    private IntegerItem txtDuracionArticulo;
    private RadioGroupItem articuloStatusRg;
    private DynamicForm frmAdministracionArticulo, frmMateriasPrimas, frmResultados;
    private Button btnGuardar, btnLimpiar;
    private SectionStackSection stsAdministracionArticulo;
    private ButtonItem btnMostrar, btnAgregar, btnEliminar;
    private SectionStackSection stsMateriasPrimas;
    private TextItem txtCodigoMatPri, txtDescripcionMatPrima;
    private IntegerItem txtCantidad;
    private SectionStackSection stsResultados;
    private HLayout hlyAccionesAdministracionArticulo;
    private Articulo articulo;
    private MateriaPrima materiaPrima;
    private ListGrid materiasPrimasArticuloGrid;

    public EdicionArticulo() {
        super("Articulo", "100%");
        stsAdministracionArticulo = new SectionStackSection();
        stsAdministracionArticulo.setShowHeader(false);
        stsAdministracionArticulo.setCanCollapse(false);
        stsAdministracionArticulo.setExpanded(true);

        frmAdministracionArticulo = new DynamicForm();
        frmAdministracionArticulo.setWidth100();
        frmAdministracionArticulo.setNumCols(4);

        RegExpValidator codigoValidator = new RegExpValidator();
        codigoValidator.setErrorMessage("Debe ingresar un código válido para el articulo");
        codigoValidator.setExpression("^(\\S{1}|(\\S{1}(\\s|\\S)*\\S{1}))$");

        txtCodigoArticulo = new TextItem("txtCodigoArticulo", "Código");
        txtCodigoArticulo.setRequired(true);
        txtCodigoArticulo.setLength(20);
        txtCodigoArticulo.setValidators(codigoValidator);

        txtDescripcionArticulo = new TextItem("txtDescripcionArticulo", "Descripción");
        txtDescripcionArticulo.setRequired(true);
        txtDescripcionArticulo.setLength(50);

        txtDuracionArticulo = new IntegerItem("txtDuracionArticulo", "Duración");
        txtDuracionArticulo.setRequired(true);
        txtDuracionArticulo.setLength(11);

        articuloStatusRg = new RadioGroupItem("articuloStatus", "Estado");
        articuloStatusRg.setVertical(false);
        articuloStatusRg.setRequired(true);
        LinkedHashMap<String, String> statusOption = new LinkedHashMap<String, String>();
        statusOption.put("a", "Activo");
        statusOption.put("i", "Inactivo");
        articuloStatusRg.setValueMap(statusOption);

        btnGuardar = new Button("Guardar");
        btnGuardar.addClickHandler(new ClickHandler() {

            public void onClick(ClickEvent event) {
                guardarArticulo();
            }
        });
        btnLimpiar = new Button("Limpiar");
        btnLimpiar.addClickHandler(new ClickHandler() {

            public void onClick(ClickEvent event) {
                frmAdministracionArticulo.clearValues();
                frmMateriasPrimas.clearValues();
            }
        });

        hlyAccionesAdministracionArticulo = new HLayout();
        hlyAccionesAdministracionArticulo.setMargin(15);
        hlyAccionesAdministracionArticulo.setAlign(Alignment.CENTER);
        hlyAccionesAdministracionArticulo.addMember(btnGuardar);
        hlyAccionesAdministracionArticulo.addMember(btnLimpiar);
        hlyAccionesAdministracionArticulo.setMembersMargin(15);
        setSectionContainerItems(hlyAccionesAdministracionArticulo);

        frmAdministracionArticulo.setItems(txtCodigoArticulo, txtDescripcionArticulo, txtDuracionArticulo, articuloStatusRg);
        stsAdministracionArticulo.addItem(frmAdministracionArticulo);
        addSection(stsAdministracionArticulo);

        stsMateriasPrimas = new SectionStackSection("Materias Primas");
        stsMateriasPrimas.setCanCollapse(false);
        stsMateriasPrimas.setExpanded(true);

        frmMateriasPrimas = new DynamicForm();
        frmMateriasPrimas.setWidth100();
        frmMateriasPrimas.setMargin(10);

        txtCodigoMatPri = new TextItem("txtCodigoMatPri", "Código");
        txtCodigoMatPri.setLength(11);
        txtCodigoMatPri.setDisabled(true);

        txtDescripcionMatPrima = new TextItem("txtDescripcionMatPrima", "Descripción");
        txtDescripcionMatPrima.setLength(50);
        txtDescripcionMatPrima.setDisabled(true);

        txtCantidad = new IntegerItem("txtCantidad", "Cantidad");
        txtCantidad.setLength(11);

        btnMostrar = new ButtonItem("btnMostrar", "Seleccionar");
        btnMostrar.setStartRow(false);
        btnMostrar.setEndRow(true);
        btnMostrar.addClickHandler(new com.smartgwt.client.widgets.form.fields.events.ClickHandler() {

            public void onClick(com.smartgwt.client.widgets.form.fields.events.ClickEvent event) {
                MateriaPrimaModal mpm = new MateriaPrimaModal(EdicionArticulo.this);
                mpm.setIsModal(true);
                mpm.centerInPage();
                mpm.show();
            }
        });

        frmMateriasPrimas.setItems(txtCodigoMatPri, txtDescripcionMatPrima, txtCantidad, btnMostrar);
        stsMateriasPrimas.setItems(frmMateriasPrimas);
        addSection(stsMateriasPrimas);

        stsResultados = new SectionStackSection("Materias Primas del Articulo");
        stsResultados.setCanCollapse(false);
        stsResultados.setExpanded(true);

        frmResultados = new DynamicForm();
        frmResultados.setWidth100();
        frmResultados.setNumCols(4);
        frmResultados.setMargin(10);

        materiasPrimasArticuloGrid = new ListGrid();
        materiasPrimasArticuloGrid.setWidth100();
        materiasPrimasArticuloGrid.setHeight100();
        materiasPrimasArticuloGrid.setFields(MateriaPrimaArticuloRecord.getFields());
        materiasPrimasArticuloGrid.setEmptyMessage("No hay registros para mostrar");
        materiasPrimasArticuloGrid.setSelectionType(SelectionStyle.SIMPLE);
        materiasPrimasArticuloGrid.setSelectionAppearance(SelectionAppearance.CHECKBOX);

        btnAgregar = new ButtonItem("btnAgregar", "Agregar");
        btnAgregar.setColSpan(2);
        btnAgregar.setStartRow(true);
        btnAgregar.setEndRow(false);
        btnAgregar.setAlign(Alignment.RIGHT);
        btnAgregar.addClickHandler(new com.smartgwt.client.widgets.form.fields.events.ClickHandler() {

            public void onClick(com.smartgwt.client.widgets.form.fields.events.ClickEvent event) {
                agregarMateriasPrimas();
            }
        });

        btnEliminar = new ButtonItem("btnEliminar", "Eliminar");
        btnEliminar.addClickHandler(new com.smartgwt.client.widgets.form.fields.events.ClickHandler() {

            public void onClick(com.smartgwt.client.widgets.form.fields.events.ClickEvent event) {
                final ListGridRecord[] selectedMatPrimArt = materiasPrimasArticuloGrid.getSelection();
                final List<MateriaPrimaArticulo> matPrimArts = new ArrayList<MateriaPrimaArticulo>();
                for (ListGridRecord matPrimArtRecord : selectedMatPrimArt) {
                    matPrimArts.add((MateriaPrimaArticulo) matPrimArtRecord.getAttributeAsObject("materiaPrimaArticulo"));
                }
                if (matPrimArts.isEmpty()) {
                    SC.warn("Advertencia", "Señor usuario, debe seleccionar al menos una materia prima para realizar la eiminación", new BooleanCallback() {

                        @Override
                        public void execute(Boolean value) {
                        }
                    }, new Dialog());
                    return;
                }
                SC.confirm("Confirmar Desactivación", "¿Señor usuario, está seguro que desea desactivar las materias primas seleccionadas?", new BooleanCallback() {

                    public void execute(Boolean value) {
                        if (value) {
                            if (selectedMatPrimArt.length > 0) {
                                for (int i = 0; i < selectedMatPrimArt.length; i++) {
                                    materiasPrimasArticuloGrid.removeData(selectedMatPrimArt[i]);
                                }
                            }
                            //materiasPrimasArticuloGrid.removeSelectedData();
                            SC.say("Señor usuario, la(las) materias primas seleccionada(s) fueron desactivadas correctamente");
                        }
                    }
                });
            }
        });
        btnEliminar.setColSpan(2);
        btnEliminar.setStartRow(false);
        btnEliminar.setEndRow(true);
        btnEliminar.setAlign(Alignment.LEFT);

        frmResultados.setItems(btnAgregar, btnEliminar);
        stsResultados.setItems(frmResultados, materiasPrimasArticuloGrid);
        addSection(stsResultados);
    }

    public EdicionArticulo(final Articulo articulo) {
        this();
        this.articulo = articulo;
        setSectionTitle(0, "Editar Articulo");
        txtCodigoArticulo.setValue(articulo.getDsid());
        txtDescripcionArticulo.setValue(articulo.getDsdescripcion());
        txtDuracionArticulo.setValue(articulo.getNmduracion());
        btnLimpiar.setDisabled(true);
        txtCodigoArticulo.setDisabled(true);
        if (articulo.getSnestado()) {
            articuloStatusRg.setValue("a");
        } else {
            articuloStatusRg.setValue("i");
        }

        for (MateriaPrimaArticulo materiaPrimaArticulo : articulo.getMateriaPrimaArticuloList()) {
            materiasPrimasArticuloGrid.addData(new MateriaPrimaArticuloRecord((materiaPrimaArticulo)));
        }
    }

    private void guardarArticulo() {
        if (frmAdministracionArticulo.validate()) {
            if (articulo == null) {
                Loader.showLoader();
                final Articulo tmp = getArticulo();
                AsyncCallback<Void> registrarCallback = new AsyncCallback<Void>() {

                    @Override
                    public void onFailure(Throwable caught) {
                        SC.warn("Error", caught.getMessage(), new BooleanCallback() {

                            @Override
                            public void execute(Boolean value) {
                            }
                        }, new Dialog());
                        articulo = null;
                        Loader.hideLoader();
                    }

                    @Override
                    public void onSuccess(Void result) {
                        articulo = tmp;
                        txtCodigoArticulo.setDisabled(true);
                        btnLimpiar.setDisabled(true);
                        SC.say("Señor usuario, el registro fue guardado correctamente");
                        final ConsultaArticulo ca = new ConsultaArticulo();
                        EdicionArticulo.this.hide();
                        ca.setLayoutData("Consultar Articulos");
                        ((Layout) EdicionArticulo.this.getParentElement()).addMember(ca);
                        Loader.hideLoader();
                    }
                };
                getArticuloService().guardarArticulo(tmp, registrarCallback);
            } else {
                final Articulo tmp = getArticulo();
                AsyncCallback<Void> actualizarCallback = new AsyncCallback<Void>() {

                    @Override
                    public void onFailure(Throwable caught) {
                        SC.warn("Error", caught.getMessage(), new BooleanCallback() {

                            @Override
                            public void execute(Boolean value) {
                            }
                        }, new Dialog());
                        Loader.hideLoader();
                    }

                    @Override
                    public void onSuccess(Void result) {
                        articulo = tmp;
                        SC.say("Señor usuario, el registro fue actualizado correctamente");
                        final ConsultaArticulo ca = new ConsultaArticulo();
                        EdicionArticulo.this.hide();
                        ca.setLayoutData("Consultar Articulos");
                        ((Layout) EdicionArticulo.this.getParentElement()).addMember(ca);
                        Loader.hideLoader();
                    }
                };
                getArticuloService().actualizarArticulo(tmp, actualizarCallback);
            }
        }
    }

    private Articulo getArticulo() {
        if (articulo == null) {
            articulo = new Articulo();
            articulo.setArticuloLineaList(new ArrayList<ArticuloLinea>());
            articulo.setDetalleSolicitudProduccionList(new ArrayList<DetalleSolicitudProduccion>());
        }

        articulo.setDsid(txtCodigoArticulo.getValueAsString());
        articulo.setDsdescripcion(txtDescripcionArticulo.getValueAsString());

        if (txtDuracionArticulo.getValueAsString() != null) {
            articulo.setNmduracion(Integer.valueOf(txtDuracionArticulo.getValueAsString()));
        } else {
            articulo.setNmduracion(0);
        }

        if (articuloStatusRg.getValueAsString().equals("a")) {
            articulo.setSnestado(true);
        } else {
            articulo.setSnestado(false);
        }

        List<MateriaPrimaArticulo> materiaPrimaArticulo = new ArrayList<MateriaPrimaArticulo>();
        ListGridRecord[] records = materiasPrimasArticuloGrid.getRecords();
        if (records.length > 0) {
            for (int i = 0; i < records.length; i++) {
                MateriaPrimaArticulo mpa = (MateriaPrimaArticulo) records[i].getAttributeAsObject("materiaPrimaArticulo");
                mpa.setMateriaPrimaArticuloPK(new MateriaPrimaArticuloPK(txtCodigoArticulo.getValueAsString(), mpa.getMateriaPrima().getNmid()));
                mpa.setArticulo(articulo);
                materiaPrimaArticulo.add(mpa);
            }
        }

        articulo.setMateriaPrimaArticuloList(materiaPrimaArticulo);

        return articulo;
    }

    public void modalMateriaPrima(MateriaPrima selection) {
        if (selection != null) {
            txtCodigoMatPri.setValue(selection.getNmid());
            txtDescripcionMatPrima.setValue(selection.getDsdescripcion());
            txtCantidad.clearValue();
            materiaPrima = selection;
        }
    }

    private void agregarMateriasPrimas() {
        if (txtCodigoMatPri.getValueAsString() != null) {
            if (txtCantidad.getValueAsString() != null) {
                ListGridRecord[] records = materiasPrimasArticuloGrid.getRecords();
                Boolean existe = false;
                if (records.length > 0) {
                    for (int i = 0; i < records.length; i++) {
                        if (records[i].getAttributeAsInt(MateriaPrimaArticuloDS.CODIGOMATPRI) == materiaPrima.getNmid()) {
                            existe = true;
                            break;
                        }
                    }
                }

                if (!existe) {
                    MateriaPrimaArticulo materiaPrimaArticulo = new MateriaPrimaArticulo();
                    materiaPrimaArticulo.setMateriaPrima(materiaPrima);
                    materiaPrimaArticulo.setNmcantidad(Integer.valueOf(txtCantidad.getValueAsString()));
                    materiasPrimasArticuloGrid.addData(new MateriaPrimaArticuloRecord(materiaPrimaArticulo));
                    frmMateriasPrimas.clearValues();
                } else {
                    SC.warn("Advertencia", "Señor usuario, la materia prima ya se encuentra asociada al articulo", new BooleanCallback() {

                        @Override
                        public void execute(Boolean value) {
                        }
                    }, new Dialog());
                    existe = true;
                    frmMateriasPrimas.clearValues();
                    return;
                }
            } else {
                SC.warn("Advertencia", "Señor usuario, debe ingresar una cantidad para la materia prima", new BooleanCallback() {

                    @Override
                    public void execute(Boolean value) {
                    }
                }, new Dialog());
                return;
            }
        } else {
            SC.warn("Advertencia", "Señor usuario, debe seleccionar como mínimo una materia prima", new BooleanCallback() {

                @Override
                public void execute(Boolean value) {
                }
            }, new Dialog());
            return;
        }
    }

    private ArticuloServiceAsync getArticuloService() {
        return GWT.create(ArticuloService.class);
    }
}
